#pragma once

#ifdef __cplusplus
extern "C"
{
#endif

enum
{
    __NX_ABS_EVENT = 0,
    __NX_KEYDOWN_EVENT,
    __NX_KEYUP_EVENT,
    __NX_MOUSEBUTTONDOWN_EVENT,
    __NX_MOUSEBUTTONUP_EVENT,
    __NX_MOUSEWHELLUP_EVENT,
    __NX_MOUSEWHELLDOWN_EVENT,
    __NX_QUIT_EVENT,
    __NX_ROOT_ABS_EVENT,
    __NX_FLUSH_EVENT,
    __NX_MOUSE_IN_EVENT,
    __NX_MOUSE_OUT_EVENT,
    __NX_EVENT_TYPE_MAX,
};

typedef enum
{
    NX_ABS_EVENT = 1UL << __NX_ABS_EVENT,
    NX_KEYDOWN_EVENT = 1UL << __NX_KEYDOWN_EVENT,
    NX_KEYUP_EVENT = 1UL << __NX_KEYUP_EVENT,
    NX_MOUSEBUTTONDOWN_EVENT = 1UL << __NX_MOUSEBUTTONDOWN_EVENT,
    NX_MOUSEBUTTONUP_EVENT = 1UL << __NX_MOUSEBUTTONUP_EVENT,
    NX_MOUSEWHEELUP_EVENT = 1UL << __NX_MOUSEWHELLUP_EVENT,
    NX_MOUSEWHEELDOWN_EVENT = 1UL << __NX_MOUSEWHELLDOWN_EVENT,
    NX_QUIT_EVENT = 1UL << __NX_QUIT_EVENT,
    NX_ROOT_ABS_EVENT = 1UL << __NX_ROOT_ABS_EVENT,
    NX_FLUSH_EVENT = 1UL << __NX_FLUSH_EVENT,
    NX_MOUSE_IN_EVENT = 1UL << __NX_MOUSE_IN_EVENT,
    NX_MOUSE_OUT_EVENT = 1UL << __NX_MOUSE_OUT_EVENT,
    NX_EVENT_TYPE_MAX = 1UL << __NX_EVENT_TYPE_MAX,
} NX_WindowEventType;

#define NX_EVENT_MASK_ALL (NX_EVENT_TYPE_MAX - 1)
#define NX_EVENT_MASK_DEFAULT (NX_ROOT_ABS_EVENT - 1)

typedef struct
{
    NX_WindowEventType type;

    union
    {
        struct
        {
            int x, y;
            int x_root, y_root;
        } abs_event;

        struct
        {
            int code;
            int modify;
        } keydown_event;

        struct
        {
            int code;
            int modify;
        } keyup_event;
        
        struct
        {
            int x, y;
            int code;
        } mouse_buttondown_event;
        struct
        {
            int x, y;
            int code;
        } mouse_buttonup_event;
        struct
        {
            int x, y;
        } mouse_wheel_event;
        struct
        {
            int x_root, y_root;
        } root_abs_event;
    };
} NX_WindowEvent;

#ifdef __cplusplus
}
#endif